#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *


class GoToLineDialog(QDialog):
    '''
    Mimic Kate go to line number
    '''
    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.setup_ui()
        
    def setup_ui(self):
        layout = QVBoxLayout(self)
        layout.addWidget(QLabel("Go to line:"))
        
        widgets_layout = QHBoxLayout(self)
    
        layout.addLayout(widgets_layout)
        
        self.spinLineNumber = QSpinBox(self)
        self.spinLineNumber.setObjectName('spinLineNumber')
        self.spinLineNumber.setMinimum(1)
            
        self.sliderLineNumber = QSlider(self)
        self.sliderLineNumber.setOrientation(Qt.Horizontal)
        self.sliderLineNumber.setObjectName('sliderLineNumber')
        self.sliderLineNumber.setMinimum(1)
        
        widgets_layout.addWidget(self.sliderLineNumber)
        widgets_layout.addWidget(self.spinLineNumber)
        
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        
        self.connect(self.buttonBox, SIGNAL("accepted()"), self.accept)
        self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)

        
        layout.addWidget(self.buttonBox)
        
        self.setLayout(layout)
        QMetaObject.connectSlotsByName(self)
    
    
    def on_sliderLineNumber_valueChanged(self, value):
        if value != self.spinLineNumber.value():
            self.spinLineNumber.setValue(value)
    
    def on_spinLineNumber_valueChanged(self, value):
        value = int(value)
        if value != self.sliderLineNumber.value():
            self.sliderLineNumber.setValue(value)
    
    def exec_(self, code_editor):
        self.code_editor = code_editor
        lines = self.code_editor.editor.document().blockCount()
        self.sliderLineNumber.setMaximum(lines)
        self.spinLineNumber.setMaximum(lines)
        self.spinLineNumber.setFocus(Qt.MouseFocusReason)
        return QDialog.exec_(self)
    
    def accept(self):
        '''
        When the dialog is accepted, jump to the line.
        This looks inefficient, but works.
        '''
        editor = self.code_editor.editor
        current_block = editor.textCursor().blockNumber()
        desired_line = self.sliderLineNumber.value() - 1
        blk = editor.document().begin()
        i = 0
        while i < desired_line:
            if blk.isValid():
                i += 1
            blk = blk.next()
        editor.setTextCursor(QTextCursor(blk))
        editor.setFocus(Qt.MouseFocusReason)
        return QDialog.accept(self)
            